﻿using System;
using System.Linq;
using gbL.NetBoard.Helpers;
using gbL.NetBoard.Examples.DoubleMVC.Model.Requests;
using gbL.NetBoard.Examples.DoubleMVC.View.UI.Requests;
using System.Collections.Generic;
using gbL.NetBoard.Examples.DoubleMVC.View.UI.ViewModel;
using gbL.NetBoard.Examples.DoubleMVC.View.Data.Requests;
using System.Data;

namespace gbL.NetBoard.Examples.DoubleMVC.Model
{
    public class Products : MultiTypedMessageListener
    {
        public Products(Blackboard domain) : base(domain) { }

        protected override void OnMessageAdded(object message)
        {
            if (message is ProductListRequest) Process((ProductListRequest)message);
            if (message is ValidateProductRequest) Process((ValidateProductRequest)message);
            if (message is ProductDetailRequest) Process((ProductDetailRequest)message);
        }

        protected override void OnMessageRemoved(object message)
        {
            // not needed
        }

        protected override Type[] MessageTypes
        {
            get
            {
                return new[] { 
                    typeof(ProductListRequest),
                    typeof(ValidateProductRequest),
                    typeof(ProductDetailRequest)
                };
            }
        }

        private void Process(ProductListRequest productListRequest)
        {
            var taken = Messages.Take(e => e.Message == productListRequest);
            if (taken.Count == 0) return;

            ProductRowRequest request = new ProductRowRequest();
            Messages.Add(request);

            List<ListProduct> results = new List<ListProduct>();
            foreach (DataRow row in request.Results.Rows)
            {
                results.Add(new ListProduct()
                {
                    ID = (int)row["Product ID"],
                    ProductName = (string)row["Product Name"],
                    Price = (decimal)row["Unit Price"]
                });
            }

            Messages.Add(new ListViewRequest<ListProduct>() { Results = results });
        }

        private void Process(ValidateProductRequest validateProduct)
        {
            var taken = Messages.Take(e => e.Message == validateProduct);
            if (taken.Count == 0) return;

            int productID;
            if (!int.TryParse(validateProduct.ProductID, out productID))
            {
                validateProduct.IsValid = false;
                validateProduct.ValidationMessage = "Product ID could not be parsed.";
            }
            else
            {
                ProductRowRequest request = new ProductRowRequest();
                request.ProductIDs = new[] { productID };
                Messages.Add(request);
                if (request.Results == null || request.Results.Rows.Count == 0)
                {
                    validateProduct.IsValid = false;
                    validateProduct.ValidationMessage = "Product not found.";
                }
                else
                {
                    validateProduct.IsValid = true;
                }
            }
        }

        private void Process(ProductDetailRequest productDetailRequest)
        {
            var taken = Messages.Take(e => e.Message == productDetailRequest);
            if (taken.Count == 0) return;

            int productID = int.Parse(productDetailRequest.ProductID);
            ProductRowRequest request = new ProductRowRequest();
            request.ProductIDs = new[] { productID };
            Messages.Add(request);
            if (request.Results != null && request.Results.Rows.Count > 0)
            {
                DetailRequest detailRequest = new DetailRequest();
                detailRequest.Title = "Product Detail";
                detailRequest.Values = new Dictionary<string, object>();
                DataRow row = request.Results.Rows[0];
                foreach (DataColumn col in request.Results.Columns)
                {
                    detailRequest.Values.Add(col.ColumnName, row[col]);
                }
                Messages.Add(detailRequest);
            }
        }
    }
}
